package com.molichuxing.gateway.bff.car.services.impl;

import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.molichuxing.framework.exception.BizException;
import com.molichuxing.gateway.bff.car.convertor.Convert;
import com.molichuxing.gateway.bff.car.entity.response.CarDeliveryCheckVo;
import com.molichuxing.gateway.bff.car.entity.response.CarDeliveryVo;
import com.molichuxing.gateway.bff.car.entity.response.CarOrderCheckVo;
import com.molichuxing.gateway.bff.car.entity.response.FenceCheckVo;
import com.molichuxing.gateway.bff.car.entity.response.PdiCheckVo;
import com.molichuxing.gateway.bff.car.services.CheckBffService;
import com.molichuxing.gateway.property.CheckTypeEnum;
import com.molichuxing.gateway.utils.RequestAttrUtil;
import com.molichuxing.services.business.dto.response.CarDetailBizDto;
import com.molichuxing.services.business.dto.response.OrderBizDto;
import com.molichuxing.services.business.dto.response.OrderExclusivelBizDto;
import com.molichuxing.services.business.dto.response.OrderSubscribeBizDto;
import com.molichuxing.services.business.dto.response.StoreBizDto;
import com.molichuxing.services.business.service.CarBizService;
import com.molichuxing.services.business.service.CarCheckBizService;
import com.molichuxing.services.business.service.OrderBizService;
import com.molichuxing.services.business.service.StoreBizService;
import com.molichuxing.services.business.service.VehicleBizService;
import com.molichuxing.services.exception.OrderExceptionCodeEnum;
import com.molichuxing.services.infrastructure.dto.response.CarDto;
import com.molichuxing.services.infrastructure.dto.response.OrderDto;
import com.molichuxing.services.infrastructure.dto.response.OrderExclusivelDto;
import com.molichuxing.services.infrastructure.dto.response.OrderSubscribeDto;
import com.molichuxing.services.infrastructure.dto.response.StockStoreDto;
import com.molichuxing.services.infrastructure.dto.response.UserDto;
import com.molichuxing.services.infrastructure.dto.response.VehicleColorDto;
import com.molichuxing.services.infrastructure.dto.response.VehiclePictureDto;
import com.molichuxing.services.infrastructure.service.CarService;
import com.molichuxing.services.infrastructure.service.FenceStoreStockService;
import com.molichuxing.services.infrastructure.service.IovCarService;
import com.molichuxing.services.infrastructure.service.IovFenceService;
import com.molichuxing.services.infrastructure.service.OrderExclusivelService;
import com.molichuxing.services.infrastructure.service.OrderService;
import com.molichuxing.services.infrastructure.service.OrderSubscribeService;
import com.molichuxing.services.infrastructure.service.StockStoreService;
import com.molichuxing.services.infrastructure.service.UserService;
import com.molichuxing.services.infrastructure.service.VehicleColorService;
import com.molichuxing.services.infrastructure.service.VehiclePictureService;
import com.molichuxing.services.property.CarsOperateStatusEnum;
import com.molichuxing.services.property.CarsTypeEnum;
import com.molichuxing.services.property.FenceStoreStockTypeEnum;
import com.molichuxing.services.property.OrderExclusivelStatusEnum;
import com.molichuxing.services.property.OrderSubscribeStatusEnum;
import com.molichuxing.services.property.OrderTypeEnum;
import com.molichuxing.services.property.StoreStatusEnum;

/**
 * @Author: yixuelin
 * @Description:
 * @Date: Created in 15:08 2019/9/19
 * @Modified By:
 **/
@Service("checkBffService")
public class CheckBffServiceImpl implements CheckBffService {
    private static final Logger logger = LoggerFactory.getLogger(CheckBffServiceImpl.class);


    @Resource
    private CarCheckBizService carCheckBizService;

    @Resource
    private StoreBizService storeBizService;

    @Resource
    private CarService carService;

    @Resource
    private IovCarService iovCarService;

    @Resource
    private OrderService orderService;

	@Resource
	OrderBizService orderBizService;

    @Resource
    private OrderSubscribeService orderSubscribeService;

    @Resource
    private OrderExclusivelService orderExclusivelService;

    @Resource
    private UserService userService;

    @Resource
    private CarBizService carBizService;

    @Resource
    private VehicleBizService vehicleBizService;

    @Resource
    private VehicleColorService vehicleColorService;

    @Resource
	private StockStoreService stockStoreService;

	@Resource
	private VehiclePictureService vehiclePictureService;

    @Resource
	private IovFenceService iovFenceService;

	@Resource
	private FenceStoreStockService fenceStoreStockService;

    @Override
    public PdiCheckVo getCheckReport(Long orderCode) {
        return Convert.toPdiCheckVo(carCheckBizService.getCheckReport(orderCode));
    }

//    @Override
//	public Boolean createCheckVo(HandoverCreateVo createVo) throws BizException, Exception {
//        // 验证门店信息
//        StoreBaseBizDto store = null;
//
//
//        //查询订单类型
//		OrderDto orderDto = orderService.getOrder(createVo.getOrderCode());
//        if (null == orderDto) {
//            throw new Exception("非法入参");
//        }
//        //下单门店id
//        Integer placeStoreId = null;
//        if (OrderTypeEnum.EXCLUSIVEL.equals(orderDto.getType())) {
//            // 专属里程订单
//            OrderExclusivelDto orderExclusivelDto = orderExclusivelService.getOrderExclusivel(checkCreateBffVo.getOrderCode());
//            if (null == orderExclusivelDto) {
//                throw new Exception("非法入参");
//            }
//            placeStoreId = orderExclusivelDto.getPlaceStoreId();
//        } else if (OrderTypeEnum.SUBSCRIBE.equals(orderDto.getType())) {
//            // 订阅里程订单
//            OrderSubscribeDto orderSubscribeDto = orderSubscribeService.getOrderSubscribe(checkCreateBffVo.getOrderCode());
//            if (null == orderSubscribeDto) {
//                throw new Exception("非法入参");
//            }
//            placeStoreId = orderSubscribeDto.getPlaceStoreId();
//        }
//
//
//        store = checkStore(storeBizService.getStoreBaseById(placeStoreId));
//
//        //验证车辆
//        checkCar(carService.getCarById(checkCreateBffVo.getCarId()));
//
//
//        //组装验车单信息
//        HandoverCreateBizDto checkCreateBizDto = new HandoverCreateBizDto();
//        //转换检验单参数
//        HandoverCheckVo checkParamsVo = Convert.toCheckParamsVo(checkCreateBffVo);
//        BeanUtils.copyProperties(checkCreateBffVo, checkCreateBizDto);
//
//        checkCreateBizDto.setType(CarCheckTypeEnum.PDI.getValue());
//        checkCreateBizDto.setReturnStoreId(store.getStoreId());
//        checkCreateBizDto.setDealerId(store.getDealerId());
//        checkCreateBizDto.setStatus(CarCheckStatusEnum.NO_CHECK.getValue());
//        checkCreateBizDto.setCarCheckInfo(JSONObject.toJSONString(checkParamsVo));
//
//        //保存验车单信息
//        int ret = carCheckBizService.createCheckBizDto(checkCreateBizDto);
//        if (ret < 1) {
//            throw new Exception("失败");
//        }
//
//        return true;
//    }

    /**
     * 根据车架号获取已行驶里程
     *
     * @param vin
     * @return
     */
    @Override
    public Integer getMileageByVin(String vin) throws Exception {
		return iovCarService.getCurrentMileage(vin);
    }

    @Override
    public CarOrderCheckVo getCarOrderCheckVo(Long orderCode, Integer carId) throws Exception {

        //查询订单类型
        OrderDto orderDto = orderService.getOrder(orderCode);
        if (null == orderDto) {
            throw new Exception("非法入参");
        }

        CarOrderCheckVo carOrderCheckVo = new CarOrderCheckVo();

        Integer userId = null;
        String goodsNameStr = "";
        if (OrderTypeEnum.EXCLUSIVEL.equals(orderDto.getType())) {
            // 专属里程订单
            OrderExclusivelDto orderExclusivelDto = orderExclusivelService.getOrderExclusivel(orderCode);
            if (null == orderExclusivelDto) {
                throw new Exception("非法入参");
            }

            userId = orderExclusivelDto.getUserId();
            carOrderCheckVo.setOrderType(OrderTypeEnum.EXCLUSIVEL.getValue());
            //车型名称+规格（是否回购/租期/付款方式）  例：北汽新能源EC 220 经典版 回购/36期/全款
            goodsNameStr = (orderExclusivelDto.getIsBuyback() ? "回购/" : "不回购/").concat(orderExclusivelDto.getTransportTime() + "月/").concat(orderExclusivelDto.getPaymentMethod().getName());
        } else if (OrderTypeEnum.SUBSCRIBE.equals(orderDto.getType())) {
            // 订阅里程订单
            OrderSubscribeDto orderSubscribeDto = orderSubscribeService.getOrderSubscribe(orderCode);
            if (null == orderSubscribeDto) {
                throw new Exception("非法入参");
            }

            userId = orderSubscribeDto.getUserId();
            carOrderCheckVo.setOrderType(OrderTypeEnum.SUBSCRIBE.getValue());
            //车型名称+规则（租期/基础里程，订阅里程）   例：北汽新能源 EC 220 精英版 1个月/500公里，300公里
            goodsNameStr = (orderSubscribeDto.getTransportTime() + "期/").concat(orderSubscribeDto.getBaseMileage() + "公里,").concat(orderSubscribeDto.getPackageMileage() + "公里");
        }

        //获取用户信息
        UserDto userDto = userService.getUser(userId);
        if (null == userDto) {
            throw new Exception("非法入参");
        }
        //获取车辆信息
        CarDetailBizDto carDetailBizDto = carBizService.getCarDetail(carId);
        if (null == carDetailBizDto) {
            throw new Exception("非法入参");
        }
        //获取车型名称
        String vehicleName = vehicleBizService.getVehicleName(carDetailBizDto.getVehicleId());
        if (null == vehicleName) {
            throw new Exception("非法入参");
        }
        //获取车身颜色
        VehicleColorDto vehicleColorDto = vehicleColorService.getVehicleColorByvehicleColorId(carDetailBizDto.getVehicleColorId());
        if (null == vehicleColorDto) {
            throw new Exception("非法入参");
        }

        carOrderCheckVo.setRealName(userDto.getRealName());
        carOrderCheckVo.setPhone(userDto.getPhone());
        carOrderCheckVo.setTypeStr(CheckTypeEnum.LIFT_CAR.getName());
        //商品名称
        carOrderCheckVo.setGoodsName(vehicleName + " " + goodsNameStr);
        carOrderCheckVo.setVehicleColor(vehicleName + "/" + vehicleColorDto.getName());
        carOrderCheckVo.setVin(carDetailBizDto.getVin());
        carOrderCheckVo.setLicencePlate(carDetailBizDto.getLicencePlate());
        carOrderCheckVo.setEngineCode(carDetailBizDto.getEngineCode());

        return carOrderCheckVo;
    }

    /**
     * 交付车辆列表
     *
     * @param orderCode
     * @return
     * @throws Exception
     */
    @Override
    public List<CarDeliveryVo> getDeliveryCarList(Long orderCode) throws Exception {
        Integer userId = RequestAttrUtil.getCurrentUserId();
        if (null == userId) {
            throw new Exception("用户未登录");
        }

        // 查询订单信息
        OrderBizDto orderBizDto = orderBizService.getOrder(orderCode);
        if (orderBizDto == null) {
            logger.error("订单({})不存在", orderCode);
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(), "订单不存在");
        } else if (!orderBizDto.getUserId().equals(userId)) {
            logger.error("该用户({})无此订单({})", userId, orderCode);
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "订单异常");
        }

        Integer storeId = null;
        Integer vehicleId = null;
        Integer vehicleType=null;
        // 判断订单业务类型
        OrderTypeEnum orderType = orderBizDto.getType();
        if (OrderTypeEnum.EXCLUSIVEL.equals(orderType)) {
            OrderExclusivelDto orderExclusivelDto = orderExclusivelService.getOrderExclusivel(orderCode);
            if (null == orderExclusivelDto) {
                logger.error("订单({})不存在", orderCode);
                throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(), "订单不存在");
            }

            storeId = orderExclusivelDto.getPlaceStoreId();
            vehicleId = orderExclusivelDto.getVehicleId();
            vehicleType=CarsTypeEnum.NEW_CAR.getValue();
        } else if (OrderTypeEnum.SUBSCRIBE.equals(orderType)) {
            OrderSubscribeDto orderSubscribeDto = orderSubscribeService.getOrderSubscribe(orderCode);
            if (null == orderSubscribeDto) {
                logger.error("订单({})不存在", orderCode);
                throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(), "订单不存在");
            }

            storeId = orderSubscribeDto.getPlaceStoreId();
            vehicleId = orderSubscribeDto.getVehicleId();
            vehicleType=CarsTypeEnum.USED_CAR.getValue();
        } else {
            logger.error("订单类型({}:{})错误", orderType.toString(), orderType.getName());
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "订单异常");
        }

        // TODO checkStore(storeBizService.getStoreBaseById(storeId));

        StockStoreDto stockStoreDto = stockStoreService.getStockStoreByStoreId(storeId);
        if (null == stockStoreDto) {
            logger.error("门店({})仓库不存在", storeId);
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(), "门店仓库不存在");
        }

        Integer stockId = stockStoreDto.getStockId();
        List<CarDto> carDtoList = carService.getSearchCarList(stockId, vehicleId, vehicleType, CarsOperateStatusEnum.FOR_RENT.getValue());
        String serverUrl = "";
        List<VehiclePictureDto> vehiclePictureDtoList = vehiclePictureService.getVehiclePictureByVehicleId(vehicleId);
        if (vehiclePictureDtoList != null && vehiclePictureDtoList.size() > 0) {
            serverUrl = vehiclePictureDtoList.get(0).getServerUrl();
        }

        return Convert.toCarDeliveryVo(carDtoList,serverUrl,orderType);
    }

	/**
	 * 还车交付车辆信息
	 * 
	 * @param orderCode
	 *            订单号
	 * @param deviceNum
	 *            大屏设备编号
	 * @param userId
	 *            用户id
	 * @return
	 * @throws Exception
	 */
	@Override
	public CarDeliveryVo getReturnCar(Long orderCode, String deviceNum, Integer userId) throws Exception {
		// 根据订单号查询订单信息
		OrderBizDto order = orderBizService.getOrder(orderCode);
		// 判断订单信息
		if (order == null) {
			return null;
		} else if (!order.getUserId().equals(userId)) {
			logger.error("[getReturnCar]订单({})用户({})和操作用户({})不一致", orderCode, order.getUserId(), userId);
			throw new BizException("订单用户不一致");
		}
		Integer storeId = null, // 门店id
				carId = null, // 车辆id
				vehicleId = null;// 车型id

		// 判断订单类型
		if (OrderTypeEnum.SUBSCRIBE.equals(order.getType())) {
			// 订阅订单
			OrderSubscribeBizDto orderSubscribe = (OrderSubscribeBizDto) order;
			if (!OrderSubscribeStatusEnum.TRADE_USE.equals(orderSubscribe.getOrderStatus())) {
				logger.error("[getReturnCar]订单({})状态({})已改变", orderCode, orderSubscribe.getOrderStatus());
				throw new BizException("订单状态已改变不可还车");
			} else if (orderSubscribe.getIsHaveSuborder()) {
				logger.error("[getReturnCar]订单({})存在续订单，不可还车", orderCode, orderSubscribe.getOrderStatus());
				throw new BizException("订单存在续订单，不可还车");
			}
			storeId = orderSubscribe.getPlaceStoreId(); // 门店id
			carId = orderSubscribe.getCarId(); // 车辆id
			vehicleId = orderSubscribe.getVehicleId();// 车型id
		} else if (OrderTypeEnum.EXCLUSIVEL.equals(order.getType())) {
			// 专属订单
			OrderExclusivelBizDto orderExclusivel = (OrderExclusivelBizDto) order;
			if (!OrderExclusivelStatusEnum.RENEGE_ACCEPTED.equals(orderExclusivel.getOrderStatus())) {
				logger.error("[getReturnCar]订单({})状态({})已改变", orderCode, orderExclusivel.getOrderStatus());
				throw new BizException("订单状态已改变不可还车");
			} else if (orderExclusivel.getCarId() == null || orderExclusivel.getCarId() == 0) {
				logger.error("[getReturnCar]订单({})未提车", orderCode, orderExclusivel.getOrderStatus());
				throw new BizException("订单未提车，无需还车");
			}
			storeId = orderExclusivel.getPlaceStoreId(); // 门店id
			carId = orderExclusivel.getCarId(); // 车辆id
			vehicleId = orderExclusivel.getVehicleId();// 车型id
		} else {
			logger.error("[getReturnCar]订单({})类型({})不可还车", orderCode, order.getType());
			throw new BizException("订单不可还车");
		}

		// 查询门店信息
		StoreBizDto store = storeBizService.getStoreDetailsByCpu(deviceNum);
		// 验证门店信息
		checkStore(store, deviceNum, storeId);
		// 查询车辆信息
		CarDto carDto = carService.getCarById(carId);
		if (carDto == null) {
			logger.error("[getReturnCar]车辆({})不存在", carId);
			throw new BizException("车辆信息异常");
		}
		// 查询车辆图片
		String serverUrl = null;
		List<VehiclePictureDto> vehiclePictureDtoList = vehiclePictureService
				.getVehiclePictureByVehicleId(vehicleId);
		if (vehiclePictureDtoList != null && !vehiclePictureDtoList.isEmpty()) {
			for (VehiclePictureDto vehiclePictureDto : vehiclePictureDtoList) {
				if (vehiclePictureDto.getPicType() == 1 && vehiclePictureDto.getIsWhiteBg()) {
					serverUrl = vehiclePictureDto.getServerUrl();
					break;
				}
			}
		}

		return Convert.toCarDeliveryVo(carDto, serverUrl, order.getType());
	}

	private void checkStore(StoreBizDto store, String deviceNum, Integer placeStoreId) {
		if (store == null) {
			// 门店不存在
			logger.error("[checkStore]大屏cpu(" + deviceNum + ")关联门店未查到");
			throw new BizException("门店信息异常");
		} else if (!store.getStoreId().equals(placeStoreId)) {
			// 还车门店不是下单门店
			logger.error("[checkStore]还车门店(" + store.getStoreId() + ")不是下单门店(" + placeStoreId + ")");
			throw new BizException("请到下单门店进行还车");
		} else if (StoreStatusEnum.CLOSE.equals(store.getStatus())) {
			// 门店强制关店 TODO
			// logger.error("[checkStore]门店(" + store.getStoreId() + ")已强制关店");
			// throw new BizException("请到下单门店进行还车");
		}
	}

	/**
	 * 验证车辆是否在门店围栏
	 * 
	 * @param carId
	 *            车辆id
	 * @param deviceNum
	 *            大屏设备编号
	 * @return
	 * @throws Exception
	 */
	@Override
	public FenceCheckVo getFenceCheck(Integer carId, String deviceNum) throws Exception {
		FenceCheckVo result = null;
		// 围栏验证
		result = new FenceCheckVo();
		result.setIsInFence(true);

		// 查询车辆信息
		CarDto carDto = carService.getCarById(carId);
		if (carDto == null) {
			logger.error("[getFenceCheck]车辆({})不存在", carId);
			throw new BizException("车辆信息异常");
		}
		// 查询门店信息
		StoreBizDto store = storeBizService.getStoreDetailsByCpu(deviceNum);
		if (store == null) {
			logger.error("[getFenceCheck]大屏cpu(" + deviceNum + ")关联门店未查到");
			throw new BizException("门店信息异常");
		}
		// 检验车辆是否在门店围栏
		result = new FenceCheckVo();
		List<Integer> fenceIdList = fenceStoreStockService.getFenceByStoreId(store.getStoreId(),
				FenceStoreStockTypeEnum.STORE);
		if (null == fenceIdList || fenceIdList.size() < 1) {
			result.setIsInFence(false);
			return result;
		}

		if (iovFenceService.getInFenceId(fenceIdList, carDto.getVin()) > 0) {
			// 车辆在围栏中
			result.setIsInFence(true);
		} else {
			result.setIsInFence(false);
			result.setMessage("车辆不在指定还车区域，请将车辆停放在门店内");
		}

		return result;
	}

	/**
	 * 交付车辆检验
	 * 
	 * @param carId
	 *            车辆id
	 * @param deviceNum
	 *            大屏设备编号
	 * @return
	 * @throws Exception
	 */
	@Override
	public CarDeliveryCheckVo getCarDeliveryCheck(Integer carId, String deviceNum) throws Exception {
		CarDeliveryCheckVo result = new CarDeliveryCheckVo();

		// TODO 门店状态

		// 查询车辆信息
		CarDto carDto = carService.getCarById(carId);
		// 车辆状态
		if (carDto == null) {
			logger.error("[getCarDeliveryCheck]车辆({})不存在", carId);
			return result.fail("该车辆数据异常", "请您更换一台车辆");
		} else if (CarsOperateStatusEnum.RENTED.getValue() == carDto.getStatus()) {
			// 车辆租赁中
			logger.error("[getCarDeliveryCheck]车辆(" + carId + ")租赁中");
			return result.fail("该车辆数据异常", "请您更换一台车辆");
		} else if (CarsOperateStatusEnum.NOT_RENT.getValue() == carDto.getStatus()) {
			// 车辆不可租
			logger.error("[getCarDeliveryCheck]车辆(" + carId + ")不可租");
			return result.fail("该车辆数据异常", "请您更换一台车辆");
		}

		// 是否有未处理里程异变
		if (iovCarService.getIsMileageExAlarms(carDto.getVin())) {
			logger.error("[checkModifyCar]车辆(" + carId + ":" + carDto.getVin() + ")存在未处理里程异变信息");
			return result.fail("该车辆仪表里程出现异常", "请您更换车辆，或联系客服处理");
		}

		return result.pass();
	}

}
